//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension IVS {
    // MARK: Enums

    public enum ChannelLatencyMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case low = "LOW"
        case normal = "NORMAL"
        public var description: String { return self.rawValue }
    }

    public enum ChannelType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case advancedHDChannelType = "ADVANCED_HD"
        case advancedSDChannelType = "ADVANCED_SD"
        case basicChannelType = "BASIC"
        case standardChannelType = "STANDARD"
        public var description: String { return self.rawValue }
    }

    public enum ContainerFormat: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fragmentedMp4 = "FRAGMENTED_MP4"
        case ts = "TS"
        public var description: String { return self.rawValue }
    }

    public enum MultitrackMaximumResolution: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fullHd = "FULL_HD"
        case hd = "HD"
        case sd = "SD"
        public var description: String { return self.rawValue }
    }

    public enum MultitrackPolicy: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case allow = "ALLOW"
        case require = "REQUIRE"
        public var description: String { return self.rawValue }
    }

    public enum RecordingConfigurationState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        case createFailed = "CREATE_FAILED"
        case creating = "CREATING"
        public var description: String { return self.rawValue }
    }

    public enum RecordingMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case disabled = "DISABLED"
        case interval = "INTERVAL"
        public var description: String { return self.rawValue }
    }

    public enum RenditionConfigurationRendition: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fullHd = "FULL_HD"
        case hd = "HD"
        case lowestResolution = "LOWEST_RESOLUTION"
        case sd = "SD"
        public var description: String { return self.rawValue }
    }

    public enum RenditionConfigurationRenditionSelection: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case all = "ALL"
        case custom = "CUSTOM"
        case none = "NONE"
        public var description: String { return self.rawValue }
    }

    public enum StreamHealth: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case healthy = "HEALTHY"
        case starving = "STARVING"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum StreamState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case live = "LIVE"
        case offline = "OFFLINE"
        public var description: String { return self.rawValue }
    }

    public enum ThumbnailConfigurationResolution: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fullHd = "FULL_HD"
        case hd = "HD"
        case lowestResolution = "LOWEST_RESOLUTION"
        case sd = "SD"
        public var description: String { return self.rawValue }
    }

    public enum ThumbnailConfigurationStorage: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case latest = "LATEST"
        case sequential = "SEQUENTIAL"
        public var description: String { return self.rawValue }
    }

    public enum TranscodePreset: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case constrainedBandwidthTranscodePreset = "CONSTRAINED_BANDWIDTH_DELIVERY"
        case higherBandwidthTranscodePreset = "HIGHER_BANDWIDTH_DELIVERY"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AccessDeniedException: AWSErrorShape {
        /// User does not have sufficient access to perform this action.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct AudioConfiguration: AWSDecodableShape {
        /// Number of audio channels.
        public let channels: Int64?
        /// Codec used for the audio encoding.
        public let codec: String?
        /// Number of audio samples recorded per second.
        public let sampleRate: Int64?
        /// The expected ingest bitrate (bits per second). This is configured in the encoder.
        public let targetBitrate: Int64?
        /// Name of the audio track (if the stream has an audio track). If multitrack is not enabled, this is track0 (the sole track).
        public let track: String?

        @inlinable
        public init(channels: Int64? = nil, codec: String? = nil, sampleRate: Int64? = nil, targetBitrate: Int64? = nil, track: String? = nil) {
            self.channels = channels
            self.codec = codec
            self.sampleRate = sampleRate
            self.targetBitrate = targetBitrate
            self.track = track
        }

        private enum CodingKeys: String, CodingKey {
            case channels = "channels"
            case codec = "codec"
            case sampleRate = "sampleRate"
            case targetBitrate = "targetBitrate"
            case track = "track"
        }
    }

    public struct BatchError: AWSDecodableShape {
        /// ARN of an IVS resource; e.g., channel.
        public let arn: String?
        /// Error code.
        public let code: String?
        /// Error message, determined by the application.
        public let message: String?

        @inlinable
        public init(arn: String? = nil, code: String? = nil, message: String? = nil) {
            self.arn = arn
            self.code = code
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case code = "code"
            case message = "message"
        }
    }

    public struct BatchGetChannelRequest: AWSEncodableShape {
        /// Array of ARNs, one per channel.
        public let arns: [String]

        @inlinable
        public init(arns: [String]) {
            self.arns = arns
        }

        public func validate(name: String) throws {
            try self.arns.forEach {
                try validate($0, name: "arns[]", parent: name, max: 128)
                try validate($0, name: "arns[]", parent: name, min: 1)
                try validate($0, name: "arns[]", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            }
            try self.validate(self.arns, name: "arns", parent: name, max: 50)
            try self.validate(self.arns, name: "arns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arns = "arns"
        }
    }

    public struct BatchGetChannelResponse: AWSDecodableShape {
        public let channels: [Channel]?
        /// Each error object is related to a specific ARN in the request.
        public let errors: [BatchError]?

        @inlinable
        public init(channels: [Channel]? = nil, errors: [BatchError]? = nil) {
            self.channels = channels
            self.errors = errors
        }

        private enum CodingKeys: String, CodingKey {
            case channels = "channels"
            case errors = "errors"
        }
    }

    public struct BatchGetStreamKeyRequest: AWSEncodableShape {
        /// Array of ARNs, one per stream key.
        public let arns: [String]

        @inlinable
        public init(arns: [String]) {
            self.arns = arns
        }

        public func validate(name: String) throws {
            try self.arns.forEach {
                try validate($0, name: "arns[]", parent: name, max: 128)
                try validate($0, name: "arns[]", parent: name, min: 1)
                try validate($0, name: "arns[]", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:stream-key/[a-zA-Z0-9-]+$")
            }
            try self.validate(self.arns, name: "arns", parent: name, max: 50)
            try self.validate(self.arns, name: "arns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arns = "arns"
        }
    }

    public struct BatchGetStreamKeyResponse: AWSDecodableShape {
        public let errors: [BatchError]?
        public let streamKeys: [StreamKey]?

        @inlinable
        public init(errors: [BatchError]? = nil, streamKeys: [StreamKey]? = nil) {
            self.errors = errors
            self.streamKeys = streamKeys
        }

        private enum CodingKeys: String, CodingKey {
            case errors = "errors"
            case streamKeys = "streamKeys"
        }
    }

    public struct BatchStartViewerSessionRevocationError: AWSDecodableShape {
        /// Channel ARN.
        public let channelArn: String
        /// Error code.
        public let code: String?
        /// Error message, determined by the application.
        public let message: String?
        /// The ID of the viewer session to revoke.
        public let viewerId: String

        @inlinable
        public init(channelArn: String, code: String? = nil, message: String? = nil, viewerId: String) {
            self.channelArn = channelArn
            self.code = code
            self.message = message
            self.viewerId = viewerId
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case code = "code"
            case message = "message"
            case viewerId = "viewerId"
        }
    }

    public struct BatchStartViewerSessionRevocationRequest: AWSEncodableShape {
        /// Array of viewer sessions, one per channel-ARN and viewer-ID pair.
        public let viewerSessions: [BatchStartViewerSessionRevocationViewerSession]

        @inlinable
        public init(viewerSessions: [BatchStartViewerSessionRevocationViewerSession]) {
            self.viewerSessions = viewerSessions
        }

        public func validate(name: String) throws {
            try self.viewerSessions.forEach {
                try $0.validate(name: "\(name).viewerSessions[]")
            }
            try self.validate(self.viewerSessions, name: "viewerSessions", parent: name, max: 20)
            try self.validate(self.viewerSessions, name: "viewerSessions", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case viewerSessions = "viewerSessions"
        }
    }

    public struct BatchStartViewerSessionRevocationResponse: AWSDecodableShape {
        /// Each error object is related to a specific channelArn and viewerId pair in the request.
        public let errors: [BatchStartViewerSessionRevocationError]?

        @inlinable
        public init(errors: [BatchStartViewerSessionRevocationError]? = nil) {
            self.errors = errors
        }

        private enum CodingKeys: String, CodingKey {
            case errors = "errors"
        }
    }

    public struct BatchStartViewerSessionRevocationViewerSession: AWSEncodableShape {
        /// The ARN of the channel associated with the viewer session to revoke.
        public let channelArn: String
        /// The ID of the viewer associated with the viewer session to revoke. Do not use this field for personally identifying, confidential, or sensitive information.
        public let viewerId: String
        /// An optional filter on which versions of the viewer session to revoke. All versions less than or equal to the specified version will be revoked. Default: 0.
        public let viewerSessionVersionsLessThanOrEqualTo: Int?

        @inlinable
        public init(channelArn: String, viewerId: String, viewerSessionVersionsLessThanOrEqualTo: Int? = nil) {
            self.channelArn = channelArn
            self.viewerId = viewerId
            self.viewerSessionVersionsLessThanOrEqualTo = viewerSessionVersionsLessThanOrEqualTo
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.validate(self.viewerId, name: "viewerId", parent: name, max: 40)
            try self.validate(self.viewerId, name: "viewerId", parent: name, min: 1)
            try self.validate(self.viewerSessionVersionsLessThanOrEqualTo, name: "viewerSessionVersionsLessThanOrEqualTo", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case viewerId = "viewerId"
            case viewerSessionVersionsLessThanOrEqualTo = "viewerSessionVersionsLessThanOrEqualTo"
        }
    }

    public struct Channel: AWSDecodableShape {
        /// Channel ARN.
        public let arn: String?
        /// Whether the channel is private (enabled for playback authorization). Default: false.
        public let authorized: Bool?
        /// Indicates which content-packaging format is used (MPEG-TS or fMP4). If multitrackInputConfiguration is specified and enabled is true, then containerFormat is required and must be set to FRAGMENTED_MP4. Otherwise, containerFormat may be set to TS or FRAGMENTED_MP4. Default: TS.
        public let containerFormat: ContainerFormat?
        /// Channel ingest endpoint, part of the definition of an ingest server, used when you set up streaming software.
        public let ingestEndpoint: String?
        /// Whether the channel allows insecure RTMP ingest. Default: false.
        public let insecureIngest: Bool?
        /// Channel latency mode. Use NORMAL to broadcast and deliver live video up to Full HD. Use LOW for near-real-time interaction with viewers. Default: LOW.
        public let latencyMode: ChannelLatencyMode?
        /// Object specifying multitrack input configuration. Default: no multitrack input configuration is specified.
        public let multitrackInputConfiguration: MultitrackInputConfiguration?
        /// Channel name.
        public let name: String?
        /// Playback-restriction-policy ARN. A valid ARN value here both specifies the ARN and enables playback restriction. Default: "" (empty string, no playback restriction policy is applied).
        public let playbackRestrictionPolicyArn: String?
        /// Channel playback URL.
        public let playbackUrl: String?
        /// Optional transcode preset for the channel. This is selectable only for ADVANCED_HD and ADVANCED_SD channel types. For those channel types, the default preset is HIGHER_BANDWIDTH_DELIVERY. For other channel types (BASIC and STANDARD), preset is the empty string ("").
        public let preset: TranscodePreset?
        /// Recording-configuration ARN. A valid ARN value here both specifies the ARN and enables recording. Default: "" (empty string, recording is disabled).
        public let recordingConfigurationArn: String?
        /// Specifies the endpoint and optional passphrase for streaming with the SRT protocol.
        public let srt: Srt?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?
        /// Channel type, which determines the allowable resolution and bitrate. If you exceed the allowable input resolution or bitrate, the stream probably will disconnect immediately. Default: STANDARD. For details, see Channel Types.
        public let type: ChannelType?

        @inlinable
        public init(arn: String? = nil, authorized: Bool? = nil, containerFormat: ContainerFormat? = nil, ingestEndpoint: String? = nil, insecureIngest: Bool? = nil, latencyMode: ChannelLatencyMode? = nil, multitrackInputConfiguration: MultitrackInputConfiguration? = nil, name: String? = nil, playbackRestrictionPolicyArn: String? = nil, playbackUrl: String? = nil, preset: TranscodePreset? = nil, recordingConfigurationArn: String? = nil, srt: Srt? = nil, tags: [String: String]? = nil, type: ChannelType? = nil) {
            self.arn = arn
            self.authorized = authorized
            self.containerFormat = containerFormat
            self.ingestEndpoint = ingestEndpoint
            self.insecureIngest = insecureIngest
            self.latencyMode = latencyMode
            self.multitrackInputConfiguration = multitrackInputConfiguration
            self.name = name
            self.playbackRestrictionPolicyArn = playbackRestrictionPolicyArn
            self.playbackUrl = playbackUrl
            self.preset = preset
            self.recordingConfigurationArn = recordingConfigurationArn
            self.srt = srt
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case authorized = "authorized"
            case containerFormat = "containerFormat"
            case ingestEndpoint = "ingestEndpoint"
            case insecureIngest = "insecureIngest"
            case latencyMode = "latencyMode"
            case multitrackInputConfiguration = "multitrackInputConfiguration"
            case name = "name"
            case playbackRestrictionPolicyArn = "playbackRestrictionPolicyArn"
            case playbackUrl = "playbackUrl"
            case preset = "preset"
            case recordingConfigurationArn = "recordingConfigurationArn"
            case srt = "srt"
            case tags = "tags"
            case type = "type"
        }
    }

    public struct ChannelNotBroadcasting: AWSErrorShape {
        /// The stream is offline for the given channel ARN.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct ChannelSummary: AWSDecodableShape {
        /// Channel ARN.
        public let arn: String?
        /// Whether the channel is private (enabled for playback authorization). Default: false.
        public let authorized: Bool?
        /// Whether the channel allows insecure RTMP ingest. Default: false.
        public let insecureIngest: Bool?
        /// Channel latency mode. Use NORMAL to broadcast and deliver live video up to Full HD. Use LOW for near-real-time interaction with viewers. Default: LOW.
        public let latencyMode: ChannelLatencyMode?
        /// Channel name.
        public let name: String?
        /// Playback-restriction-policy ARN. A valid ARN value here both specifies the ARN and enables playback restriction. Default: "" (empty string, no playback restriction policy is applied).
        public let playbackRestrictionPolicyArn: String?
        /// Optional transcode preset for the channel. This is selectable only for ADVANCED_HD and ADVANCED_SD channel types. For those channel types, the default preset is HIGHER_BANDWIDTH_DELIVERY. For other channel types (BASIC and STANDARD), preset is the empty string ("").
        public let preset: TranscodePreset?
        /// Recording-configuration ARN. A valid ARN value here both specifies the ARN and enables recording. Default: "" (empty string, recording is disabled).
        public let recordingConfigurationArn: String?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?
        /// Channel type, which determines the allowable resolution and bitrate. If you exceed the allowable input resolution or bitrate, the stream probably will disconnect immediately. Default: STANDARD. For details, see Channel Types.
        public let type: ChannelType?

        @inlinable
        public init(arn: String? = nil, authorized: Bool? = nil, insecureIngest: Bool? = nil, latencyMode: ChannelLatencyMode? = nil, name: String? = nil, playbackRestrictionPolicyArn: String? = nil, preset: TranscodePreset? = nil, recordingConfigurationArn: String? = nil, tags: [String: String]? = nil, type: ChannelType? = nil) {
            self.arn = arn
            self.authorized = authorized
            self.insecureIngest = insecureIngest
            self.latencyMode = latencyMode
            self.name = name
            self.playbackRestrictionPolicyArn = playbackRestrictionPolicyArn
            self.preset = preset
            self.recordingConfigurationArn = recordingConfigurationArn
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case authorized = "authorized"
            case insecureIngest = "insecureIngest"
            case latencyMode = "latencyMode"
            case name = "name"
            case playbackRestrictionPolicyArn = "playbackRestrictionPolicyArn"
            case preset = "preset"
            case recordingConfigurationArn = "recordingConfigurationArn"
            case tags = "tags"
            case type = "type"
        }
    }

    public struct ConflictException: AWSErrorShape {
        /// Updating or deleting a resource can cause an inconsistent state.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct CreateChannelRequest: AWSEncodableShape {
        /// Whether the channel is private (enabled for playback authorization). Default: false.
        public let authorized: Bool?
        /// Indicates which content-packaging format is used (MPEG-TS or fMP4). If multitrackInputConfiguration is specified and enabled is true, then containerFormat is required and must be set to FRAGMENTED_MP4. Otherwise, containerFormat may be set to TS or FRAGMENTED_MP4. Default: TS.
        public let containerFormat: ContainerFormat?
        /// Whether the channel allows insecure RTMP and SRT ingest. Default: false.
        public let insecureIngest: Bool?
        /// Channel latency mode. Use NORMAL to broadcast and deliver live video up to Full HD. Use LOW for near-real-time interaction with viewers. Default: LOW.
        public let latencyMode: ChannelLatencyMode?
        /// Object specifying multitrack input configuration. Default: no multitrack input configuration is specified.
        public let multitrackInputConfiguration: MultitrackInputConfiguration?
        /// Channel name.
        public let name: String?
        /// Playback-restriction-policy ARN. A valid ARN value here both specifies the ARN and enables playback restriction. Default: "" (empty string, no playback restriction policy is applied).
        public let playbackRestrictionPolicyArn: String?
        /// Optional transcode preset for the channel. This is selectable only for ADVANCED_HD and ADVANCED_SD channel types. For those channel types, the default preset is HIGHER_BANDWIDTH_DELIVERY. For other channel types (BASIC and STANDARD), preset is the empty string ("").
        public let preset: TranscodePreset?
        /// Recording-configuration ARN. A valid ARN value here both specifies the ARN and enables recording. Default: "" (empty string, recording is disabled).
        public let recordingConfigurationArn: String?
        /// Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?
        /// Channel type, which determines the allowable resolution and bitrate. If you exceed the allowable input resolution or bitrate, the stream probably will disconnect immediately. Default: STANDARD. For details, see Channel Types.
        public let type: ChannelType?

        @inlinable
        public init(authorized: Bool? = nil, containerFormat: ContainerFormat? = nil, insecureIngest: Bool? = nil, latencyMode: ChannelLatencyMode? = nil, multitrackInputConfiguration: MultitrackInputConfiguration? = nil, name: String? = nil, playbackRestrictionPolicyArn: String? = nil, preset: TranscodePreset? = nil, recordingConfigurationArn: String? = nil, tags: [String: String]? = nil, type: ChannelType? = nil) {
            self.authorized = authorized
            self.containerFormat = containerFormat
            self.insecureIngest = insecureIngest
            self.latencyMode = latencyMode
            self.multitrackInputConfiguration = multitrackInputConfiguration
            self.name = name
            self.playbackRestrictionPolicyArn = playbackRestrictionPolicyArn
            self.preset = preset
            self.recordingConfigurationArn = recordingConfigurationArn
            self.tags = tags
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.validate(self.playbackRestrictionPolicyArn, name: "playbackRestrictionPolicyArn", parent: name, max: 128)
            try self.validate(self.playbackRestrictionPolicyArn, name: "playbackRestrictionPolicyArn", parent: name, pattern: "^^$|^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-restriction-policy/[a-zA-Z0-9-]+$$")
            try self.validate(self.recordingConfigurationArn, name: "recordingConfigurationArn", parent: name, max: 128)
            try self.validate(self.recordingConfigurationArn, name: "recordingConfigurationArn", parent: name, pattern: "^^$|^arn:aws:ivs:[a-z0-9-]+:[0-9]+:recording-configuration/[a-zA-Z0-9-]+$$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case authorized = "authorized"
            case containerFormat = "containerFormat"
            case insecureIngest = "insecureIngest"
            case latencyMode = "latencyMode"
            case multitrackInputConfiguration = "multitrackInputConfiguration"
            case name = "name"
            case playbackRestrictionPolicyArn = "playbackRestrictionPolicyArn"
            case preset = "preset"
            case recordingConfigurationArn = "recordingConfigurationArn"
            case tags = "tags"
            case type = "type"
        }
    }

    public struct CreateChannelResponse: AWSDecodableShape {
        public let channel: Channel?
        public let streamKey: StreamKey?

        @inlinable
        public init(channel: Channel? = nil, streamKey: StreamKey? = nil) {
            self.channel = channel
            self.streamKey = streamKey
        }

        private enum CodingKeys: String, CodingKey {
            case channel = "channel"
            case streamKey = "streamKey"
        }
    }

    public struct CreatePlaybackRestrictionPolicyRequest: AWSEncodableShape {
        /// A list of country codes that control geoblocking restriction. Allowed values are the officially assigned ISO 3166-1 alpha-2 codes. Default: All countries (an empty array).
        public let allowedCountries: [String]?
        /// A list of origin sites that control CORS restriction. Allowed values are the same as valid values of the Origin header defined at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin. Default: All origins (an empty array).
        public let allowedOrigins: [String]?
        /// Whether channel playback is constrained by origin site. Default: false.
        public let enableStrictOriginEnforcement: Bool?
        /// Playback-restriction-policy name. The value does not need to be unique.
        public let name: String?
        /// Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(allowedCountries: [String]? = nil, allowedOrigins: [String]? = nil, enableStrictOriginEnforcement: Bool? = nil, name: String? = nil, tags: [String: String]? = nil) {
            self.allowedCountries = allowedCountries
            self.allowedOrigins = allowedOrigins
            self.enableStrictOriginEnforcement = enableStrictOriginEnforcement
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.allowedCountries?.forEach {
                try validate($0, name: "allowedCountries[]", parent: name, max: 2)
                try validate($0, name: "allowedCountries[]", parent: name, min: 2)
            }
            try self.allowedOrigins?.forEach {
                try validate($0, name: "allowedOrigins[]", parent: name, max: 128)
            }
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case allowedCountries = "allowedCountries"
            case allowedOrigins = "allowedOrigins"
            case enableStrictOriginEnforcement = "enableStrictOriginEnforcement"
            case name = "name"
            case tags = "tags"
        }
    }

    public struct CreatePlaybackRestrictionPolicyResponse: AWSDecodableShape {
        public let playbackRestrictionPolicy: PlaybackRestrictionPolicy?

        @inlinable
        public init(playbackRestrictionPolicy: PlaybackRestrictionPolicy? = nil) {
            self.playbackRestrictionPolicy = playbackRestrictionPolicy
        }

        private enum CodingKeys: String, CodingKey {
            case playbackRestrictionPolicy = "playbackRestrictionPolicy"
        }
    }

    public struct CreateRecordingConfigurationRequest: AWSEncodableShape {
        /// A complex type that contains a destination configuration for where recorded video will be stored.
        public let destinationConfiguration: DestinationConfiguration
        /// Recording-configuration name. The value does not need to be unique.
        public let name: String?
        /// If a broadcast disconnects and then reconnects within the specified interval, the multiple streams will be considered a single broadcast and merged together. Default: 0.
        public let recordingReconnectWindowSeconds: Int?
        /// Object that describes which renditions should be recorded for a stream.
        public let renditionConfiguration: RenditionConfiguration?
        /// Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?
        /// A complex type that allows you to enable/disable the recording of thumbnails for a live session and modify the interval at which thumbnails are generated for the live session.
        public let thumbnailConfiguration: ThumbnailConfiguration?

        @inlinable
        public init(destinationConfiguration: DestinationConfiguration, name: String? = nil, recordingReconnectWindowSeconds: Int? = nil, renditionConfiguration: RenditionConfiguration? = nil, tags: [String: String]? = nil, thumbnailConfiguration: ThumbnailConfiguration? = nil) {
            self.destinationConfiguration = destinationConfiguration
            self.name = name
            self.recordingReconnectWindowSeconds = recordingReconnectWindowSeconds
            self.renditionConfiguration = renditionConfiguration
            self.tags = tags
            self.thumbnailConfiguration = thumbnailConfiguration
        }

        public func validate(name: String) throws {
            try self.destinationConfiguration.validate(name: "\(name).destinationConfiguration")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.validate(self.recordingReconnectWindowSeconds, name: "recordingReconnectWindowSeconds", parent: name, max: 300)
            try self.validate(self.recordingReconnectWindowSeconds, name: "recordingReconnectWindowSeconds", parent: name, min: 0)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.thumbnailConfiguration?.validate(name: "\(name).thumbnailConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case destinationConfiguration = "destinationConfiguration"
            case name = "name"
            case recordingReconnectWindowSeconds = "recordingReconnectWindowSeconds"
            case renditionConfiguration = "renditionConfiguration"
            case tags = "tags"
            case thumbnailConfiguration = "thumbnailConfiguration"
        }
    }

    public struct CreateRecordingConfigurationResponse: AWSDecodableShape {
        public let recordingConfiguration: RecordingConfiguration?

        @inlinable
        public init(recordingConfiguration: RecordingConfiguration? = nil) {
            self.recordingConfiguration = recordingConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case recordingConfiguration = "recordingConfiguration"
        }
    }

    public struct CreateStreamKeyRequest: AWSEncodableShape {
        /// ARN of the channel for which to create the stream key.
        public let channelArn: String
        /// Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(channelArn: String, tags: [String: String]? = nil) {
            self.channelArn = channelArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case tags = "tags"
        }
    }

    public struct CreateStreamKeyResponse: AWSDecodableShape {
        /// Stream key used to authenticate an RTMPS stream for ingestion.
        public let streamKey: StreamKey?

        @inlinable
        public init(streamKey: StreamKey? = nil) {
            self.streamKey = streamKey
        }

        private enum CodingKeys: String, CodingKey {
            case streamKey = "streamKey"
        }
    }

    public struct DeleteChannelRequest: AWSEncodableShape {
        /// ARN of the channel to be deleted.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct DeletePlaybackKeyPairRequest: AWSEncodableShape {
        /// ARN of the key pair to be deleted.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-key/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct DeletePlaybackKeyPairResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeletePlaybackRestrictionPolicyRequest: AWSEncodableShape {
        /// ARN of the playback restriction policy to be deleted.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-restriction-policy/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct DeleteRecordingConfigurationRequest: AWSEncodableShape {
        /// ARN of the recording configuration to be deleted.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:recording-configuration/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct DeleteStreamKeyRequest: AWSEncodableShape {
        /// ARN of the stream key to be deleted.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:stream-key/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct DestinationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// An S3 destination configuration where recorded videos will be stored.
        public let s3: S3DestinationConfiguration?

        @inlinable
        public init(s3: S3DestinationConfiguration? = nil) {
            self.s3 = s3
        }

        public func validate(name: String) throws {
            try self.s3?.validate(name: "\(name).s3")
        }

        private enum CodingKeys: String, CodingKey {
            case s3 = "s3"
        }
    }

    public struct GetChannelRequest: AWSEncodableShape {
        /// ARN of the channel for which the configuration is to be retrieved.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct GetChannelResponse: AWSDecodableShape {
        public let channel: Channel?

        @inlinable
        public init(channel: Channel? = nil) {
            self.channel = channel
        }

        private enum CodingKeys: String, CodingKey {
            case channel = "channel"
        }
    }

    public struct GetPlaybackKeyPairRequest: AWSEncodableShape {
        /// ARN of the key pair to be returned.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-key/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct GetPlaybackKeyPairResponse: AWSDecodableShape {
        public let keyPair: PlaybackKeyPair?

        @inlinable
        public init(keyPair: PlaybackKeyPair? = nil) {
            self.keyPair = keyPair
        }

        private enum CodingKeys: String, CodingKey {
            case keyPair = "keyPair"
        }
    }

    public struct GetPlaybackRestrictionPolicyRequest: AWSEncodableShape {
        /// ARN of the playback restriction policy to be returned.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-restriction-policy/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct GetPlaybackRestrictionPolicyResponse: AWSDecodableShape {
        public let playbackRestrictionPolicy: PlaybackRestrictionPolicy?

        @inlinable
        public init(playbackRestrictionPolicy: PlaybackRestrictionPolicy? = nil) {
            self.playbackRestrictionPolicy = playbackRestrictionPolicy
        }

        private enum CodingKeys: String, CodingKey {
            case playbackRestrictionPolicy = "playbackRestrictionPolicy"
        }
    }

    public struct GetRecordingConfigurationRequest: AWSEncodableShape {
        /// ARN of the recording configuration to be retrieved.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:recording-configuration/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct GetRecordingConfigurationResponse: AWSDecodableShape {
        public let recordingConfiguration: RecordingConfiguration?

        @inlinable
        public init(recordingConfiguration: RecordingConfiguration? = nil) {
            self.recordingConfiguration = recordingConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case recordingConfiguration = "recordingConfiguration"
        }
    }

    public struct GetStreamKeyRequest: AWSEncodableShape {
        /// ARN for the stream key to be retrieved.
        public let arn: String

        @inlinable
        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:stream-key/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
        }
    }

    public struct GetStreamKeyResponse: AWSDecodableShape {
        public let streamKey: StreamKey?

        @inlinable
        public init(streamKey: StreamKey? = nil) {
            self.streamKey = streamKey
        }

        private enum CodingKeys: String, CodingKey {
            case streamKey = "streamKey"
        }
    }

    public struct GetStreamRequest: AWSEncodableShape {
        /// Channel ARN for stream to be accessed.
        public let channelArn: String

        @inlinable
        public init(channelArn: String) {
            self.channelArn = channelArn
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
        }
    }

    public struct GetStreamResponse: AWSDecodableShape {
        public let stream: Stream?

        @inlinable
        public init(stream: Stream? = nil) {
            self.stream = stream
        }

        private enum CodingKeys: String, CodingKey {
            case stream = "stream"
        }
    }

    public struct GetStreamSessionRequest: AWSEncodableShape {
        /// ARN of the channel resource
        public let channelArn: String
        /// Unique identifier for a live or previously live stream in the specified channel. If no streamId is provided, this returns the most recent stream session for the channel, if it exists.
        public let streamId: String?

        @inlinable
        public init(channelArn: String, streamId: String? = nil) {
            self.channelArn = channelArn
            self.streamId = streamId
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.validate(self.streamId, name: "streamId", parent: name, max: 26)
            try self.validate(self.streamId, name: "streamId", parent: name, min: 26)
            try self.validate(self.streamId, name: "streamId", parent: name, pattern: "^st-[a-zA-Z0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case streamId = "streamId"
        }
    }

    public struct GetStreamSessionResponse: AWSDecodableShape {
        /// List of stream details.
        public let streamSession: StreamSession?

        @inlinable
        public init(streamSession: StreamSession? = nil) {
            self.streamSession = streamSession
        }

        private enum CodingKeys: String, CodingKey {
            case streamSession = "streamSession"
        }
    }

    public struct ImportPlaybackKeyPairRequest: AWSEncodableShape {
        /// Playback-key-pair name. The value does not need to be unique.
        public let name: String?
        /// The public portion of a customer-generated key pair.
        public let publicKeyMaterial: String
        /// Any tags provided with the request are added to the playback key pair tags. See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(name: String? = nil, publicKeyMaterial: String, tags: [String: String]? = nil) {
            self.name = name
            self.publicKeyMaterial = publicKeyMaterial
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "name"
            case publicKeyMaterial = "publicKeyMaterial"
            case tags = "tags"
        }
    }

    public struct ImportPlaybackKeyPairResponse: AWSDecodableShape {
        public let keyPair: PlaybackKeyPair?

        @inlinable
        public init(keyPair: PlaybackKeyPair? = nil) {
            self.keyPair = keyPair
        }

        private enum CodingKeys: String, CodingKey {
            case keyPair = "keyPair"
        }
    }

    public struct IngestConfiguration: AWSDecodableShape {
        /// Encoder settings for audio.
        public let audio: AudioConfiguration?
        /// Encoder settings for video.
        public let video: VideoConfiguration?

        @inlinable
        public init(audio: AudioConfiguration? = nil, video: VideoConfiguration? = nil) {
            self.audio = audio
            self.video = video
        }

        private enum CodingKeys: String, CodingKey {
            case audio = "audio"
            case video = "video"
        }
    }

    public struct IngestConfigurations: AWSDecodableShape {
        /// Encoder settings for audio.
        public let audioConfigurations: [AudioConfiguration]
        /// Encoder settings for video
        public let videoConfigurations: [VideoConfiguration]

        @inlinable
        public init(audioConfigurations: [AudioConfiguration], videoConfigurations: [VideoConfiguration]) {
            self.audioConfigurations = audioConfigurations
            self.videoConfigurations = videoConfigurations
        }

        private enum CodingKeys: String, CodingKey {
            case audioConfigurations = "audioConfigurations"
            case videoConfigurations = "videoConfigurations"
        }
    }

    public struct InternalServerException: AWSErrorShape {
        /// Unexpected error during processing of request.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct ListChannelsRequest: AWSEncodableShape {
        /// Filters the channel list to match the specified name.
        public let filterByName: String?
        /// Filters the channel list to match the specified policy.
        public let filterByPlaybackRestrictionPolicyArn: String?
        /// Filters the channel list to match the specified recording-configuration ARN.
        public let filterByRecordingConfigurationArn: String?
        /// Maximum number of channels to return. Default: 100.
        public let maxResults: Int?
        /// The first channel to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(filterByName: String? = nil, filterByPlaybackRestrictionPolicyArn: String? = nil, filterByRecordingConfigurationArn: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filterByName = filterByName
            self.filterByPlaybackRestrictionPolicyArn = filterByPlaybackRestrictionPolicyArn
            self.filterByRecordingConfigurationArn = filterByRecordingConfigurationArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.filterByName, name: "filterByName", parent: name, max: 128)
            try self.validate(self.filterByName, name: "filterByName", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.validate(self.filterByPlaybackRestrictionPolicyArn, name: "filterByPlaybackRestrictionPolicyArn", parent: name, max: 128)
            try self.validate(self.filterByPlaybackRestrictionPolicyArn, name: "filterByPlaybackRestrictionPolicyArn", parent: name, pattern: "^^$|^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-restriction-policy/[a-zA-Z0-9-]+$$")
            try self.validate(self.filterByRecordingConfigurationArn, name: "filterByRecordingConfigurationArn", parent: name, max: 128)
            try self.validate(self.filterByRecordingConfigurationArn, name: "filterByRecordingConfigurationArn", parent: name, pattern: "^^$|^arn:aws:ivs:[a-z0-9-]+:[0-9]+:recording-configuration/[a-zA-Z0-9-]+$$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case filterByName = "filterByName"
            case filterByPlaybackRestrictionPolicyArn = "filterByPlaybackRestrictionPolicyArn"
            case filterByRecordingConfigurationArn = "filterByRecordingConfigurationArn"
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListChannelsResponse: AWSDecodableShape {
        /// List of the matching channels.
        public let channels: [ChannelSummary]
        /// If there are more channels than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?

        @inlinable
        public init(channels: [ChannelSummary], nextToken: String? = nil) {
            self.channels = channels
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case channels = "channels"
            case nextToken = "nextToken"
        }
    }

    public struct ListPlaybackKeyPairsRequest: AWSEncodableShape {
        /// Maximum number of key pairs to return. Default: your service quota or 100, whichever is smaller.
        public let maxResults: Int?
        /// The first key pair to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListPlaybackKeyPairsResponse: AWSDecodableShape {
        /// List of key pairs.
        public let keyPairs: [PlaybackKeyPairSummary]
        /// If there are more key pairs than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?

        @inlinable
        public init(keyPairs: [PlaybackKeyPairSummary], nextToken: String? = nil) {
            self.keyPairs = keyPairs
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case keyPairs = "keyPairs"
            case nextToken = "nextToken"
        }
    }

    public struct ListPlaybackRestrictionPoliciesRequest: AWSEncodableShape {
        /// Maximum number of policies to return. Default: 1.
        public let maxResults: Int?
        /// The first policy to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListPlaybackRestrictionPoliciesResponse: AWSDecodableShape {
        /// If there are more channels than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?
        /// List of the matching policies.
        public let playbackRestrictionPolicies: [PlaybackRestrictionPolicySummary]

        @inlinable
        public init(nextToken: String? = nil, playbackRestrictionPolicies: [PlaybackRestrictionPolicySummary]) {
            self.nextToken = nextToken
            self.playbackRestrictionPolicies = playbackRestrictionPolicies
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case playbackRestrictionPolicies = "playbackRestrictionPolicies"
        }
    }

    public struct ListRecordingConfigurationsRequest: AWSEncodableShape {
        /// Maximum number of recording configurations to return. Default: your service quota or 100, whichever is smaller.
        public let maxResults: Int?
        /// The first recording configuration to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListRecordingConfigurationsResponse: AWSDecodableShape {
        /// If there are more recording configurations than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?
        /// List of the matching recording configurations.
        public let recordingConfigurations: [RecordingConfigurationSummary]

        @inlinable
        public init(nextToken: String? = nil, recordingConfigurations: [RecordingConfigurationSummary]) {
            self.nextToken = nextToken
            self.recordingConfigurations = recordingConfigurations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case recordingConfigurations = "recordingConfigurations"
        }
    }

    public struct ListStreamKeysRequest: AWSEncodableShape {
        /// Channel ARN used to filter the list.
        public let channelArn: String
        /// Maximum number of streamKeys to return. Default: 1.
        public let maxResults: Int?
        /// The first stream key to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(channelArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.channelArn = channelArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListStreamKeysResponse: AWSDecodableShape {
        /// If there are more stream keys than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?
        /// List of stream keys.
        public let streamKeys: [StreamKeySummary]

        @inlinable
        public init(nextToken: String? = nil, streamKeys: [StreamKeySummary]) {
            self.nextToken = nextToken
            self.streamKeys = streamKeys
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case streamKeys = "streamKeys"
        }
    }

    public struct ListStreamSessionsRequest: AWSEncodableShape {
        /// Channel ARN used to filter the list.
        public let channelArn: String
        /// Maximum number of streams to return. Default: 100.
        public let maxResults: Int?
        /// The first stream to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(channelArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.channelArn = channelArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListStreamSessionsResponse: AWSDecodableShape {
        /// If there are more streams than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?
        /// List of stream sessions.
        public let streamSessions: [StreamSessionSummary]

        @inlinable
        public init(nextToken: String? = nil, streamSessions: [StreamSessionSummary]) {
            self.nextToken = nextToken
            self.streamSessions = streamSessions
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case streamSessions = "streamSessions"
        }
    }

    public struct ListStreamsRequest: AWSEncodableShape {
        /// Filters the stream list to match the specified criterion.
        public let filterBy: StreamFilters?
        /// Maximum number of streams to return. Default: 100.
        public let maxResults: Int?
        /// The first stream to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(filterBy: StreamFilters? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filterBy = filterBy
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case filterBy = "filterBy"
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListStreamsResponse: AWSDecodableShape {
        /// If there are more streams than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?
        /// List of streams.
        public let streams: [StreamSummary]

        @inlinable
        public init(nextToken: String? = nil, streams: [StreamSummary]) {
            self.nextToken = nextToken
            self.streams = streams
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case streams = "streams"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The ARN of the resource to be retrieved. The ARN must be URL-encoded.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 128)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:[a-z-]/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// Tags attached to the resource. Array of maps, each of the form string:string (key:value).
        public let tags: [String: String]

        @inlinable
        public init(tags: [String: String]) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct MultitrackInputConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Indicates whether multitrack input is enabled. Can be set to true only if channel type is STANDARD. Setting enabled to true with any other channel type will cause an exception. If true, then policy, maximumResolution, and containerFormat are required, and containerFormat must be set to FRAGMENTED_MP4. Default: false.
        public let enabled: Bool?
        /// Maximum resolution for multitrack input. Required if enabled is true.
        public let maximumResolution: MultitrackMaximumResolution?
        /// Indicates whether multitrack input is allowed or required. Required if enabled is true.
        public let policy: MultitrackPolicy?

        @inlinable
        public init(enabled: Bool? = nil, maximumResolution: MultitrackMaximumResolution? = nil, policy: MultitrackPolicy? = nil) {
            self.enabled = enabled
            self.maximumResolution = maximumResolution
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case enabled = "enabled"
            case maximumResolution = "maximumResolution"
            case policy = "policy"
        }
    }

    public struct PendingVerification: AWSErrorShape {
        ///  Your account is pending verification.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct PlaybackKeyPair: AWSDecodableShape {
        /// Key-pair ARN.
        public let arn: String?
        /// Key-pair identifier.
        public let fingerprint: String?
        /// Playback-key-pair name. The value does not need to be unique.
        public let name: String?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(arn: String? = nil, fingerprint: String? = nil, name: String? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.fingerprint = fingerprint
            self.name = name
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case fingerprint = "fingerprint"
            case name = "name"
            case tags = "tags"
        }
    }

    public struct PlaybackKeyPairSummary: AWSDecodableShape {
        /// Key-pair ARN.
        public let arn: String?
        /// Playback-key-pair name. The value does not need to be unique.
        public let name: String?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(arn: String? = nil, name: String? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.name = name
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case name = "name"
            case tags = "tags"
        }
    }

    public struct PlaybackRestrictionPolicy: AWSDecodableShape {
        /// A list of country codes that control geoblocking restriction. Allowed values are the officially assigned ISO 3166-1 alpha-2 codes. Default: All countries (an empty array).
        public let allowedCountries: [String]
        /// A list of origin sites that control CORS restriction. Allowed values are the same as valid values of the Origin header defined at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin. Default: All origins (an empty array).
        public let allowedOrigins: [String]
        /// Playback-restriction-policy ARN
        public let arn: String
        /// Whether channel playback is constrained by origin site. Default: false.
        public let enableStrictOriginEnforcement: Bool?
        /// Playback-restriction-policy name. The value does not need to be unique.
        public let name: String?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(allowedCountries: [String], allowedOrigins: [String], arn: String, enableStrictOriginEnforcement: Bool? = nil, name: String? = nil, tags: [String: String]? = nil) {
            self.allowedCountries = allowedCountries
            self.allowedOrigins = allowedOrigins
            self.arn = arn
            self.enableStrictOriginEnforcement = enableStrictOriginEnforcement
            self.name = name
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case allowedCountries = "allowedCountries"
            case allowedOrigins = "allowedOrigins"
            case arn = "arn"
            case enableStrictOriginEnforcement = "enableStrictOriginEnforcement"
            case name = "name"
            case tags = "tags"
        }
    }

    public struct PlaybackRestrictionPolicySummary: AWSDecodableShape {
        /// A list of country codes that control geoblocking restriction. Allowed values are the officially assigned ISO 3166-1 alpha-2 codes. Default: All countries (an empty array).
        public let allowedCountries: [String]
        /// A list of origin sites that control CORS restriction. Allowed values are the same as valid values of the Origin header defined at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin. Default: All origins (an empty array).
        public let allowedOrigins: [String]
        /// Playback-restriction-policy ARN
        public let arn: String
        /// Whether channel playback is constrained by origin site. Default: false.
        public let enableStrictOriginEnforcement: Bool?
        /// Playback-restriction-policy name. The value does not need to be unique.
        public let name: String?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(allowedCountries: [String], allowedOrigins: [String], arn: String, enableStrictOriginEnforcement: Bool? = nil, name: String? = nil, tags: [String: String]? = nil) {
            self.allowedCountries = allowedCountries
            self.allowedOrigins = allowedOrigins
            self.arn = arn
            self.enableStrictOriginEnforcement = enableStrictOriginEnforcement
            self.name = name
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case allowedCountries = "allowedCountries"
            case allowedOrigins = "allowedOrigins"
            case arn = "arn"
            case enableStrictOriginEnforcement = "enableStrictOriginEnforcement"
            case name = "name"
            case tags = "tags"
        }
    }

    public struct PutMetadataRequest: AWSEncodableShape {
        /// ARN of the channel into which metadata is inserted. This channel must have an active stream.
        public let channelArn: String
        /// Metadata to insert into the stream. Maximum: 1 KB per request.
        public let metadata: String

        @inlinable
        public init(channelArn: String, metadata: String) {
            self.channelArn = channelArn
            self.metadata = metadata
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.validate(self.metadata, name: "metadata", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case metadata = "metadata"
        }
    }

    public struct RecordingConfiguration: AWSDecodableShape {
        /// Recording-configuration ARN.
        public let arn: String
        /// A complex type that contains information about where recorded video will be stored.
        public let destinationConfiguration: DestinationConfiguration
        /// Recording-configuration name. The value does not need to be unique.
        public let name: String?
        /// If a broadcast disconnects and then reconnects within the specified interval, the multiple streams will be considered a single broadcast and merged together. Default: 0.
        public let recordingReconnectWindowSeconds: Int?
        /// Object that describes which renditions should be recorded for a stream.
        public let renditionConfiguration: RenditionConfiguration?
        /// Indicates the current state of the recording configuration. When the state is ACTIVE, the configuration is ready for recording a channel stream.
        public let state: RecordingConfigurationState
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?
        /// A complex type that allows you to enable/disable the recording of thumbnails for a live session and modify the interval at which thumbnails are generated for the live session.
        public let thumbnailConfiguration: ThumbnailConfiguration?

        @inlinable
        public init(arn: String, destinationConfiguration: DestinationConfiguration, name: String? = nil, recordingReconnectWindowSeconds: Int? = nil, renditionConfiguration: RenditionConfiguration? = nil, state: RecordingConfigurationState, tags: [String: String]? = nil, thumbnailConfiguration: ThumbnailConfiguration? = nil) {
            self.arn = arn
            self.destinationConfiguration = destinationConfiguration
            self.name = name
            self.recordingReconnectWindowSeconds = recordingReconnectWindowSeconds
            self.renditionConfiguration = renditionConfiguration
            self.state = state
            self.tags = tags
            self.thumbnailConfiguration = thumbnailConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case destinationConfiguration = "destinationConfiguration"
            case name = "name"
            case recordingReconnectWindowSeconds = "recordingReconnectWindowSeconds"
            case renditionConfiguration = "renditionConfiguration"
            case state = "state"
            case tags = "tags"
            case thumbnailConfiguration = "thumbnailConfiguration"
        }
    }

    public struct RecordingConfigurationSummary: AWSDecodableShape {
        /// Recording-configuration ARN.
        public let arn: String
        /// A complex type that contains information about where recorded video will be stored.
        public let destinationConfiguration: DestinationConfiguration
        /// Recording-configuration name. The value does not need to be unique.
        public let name: String?
        /// Indicates the current state of the recording configuration. When the state is ACTIVE, the configuration is ready for recording a channel stream.
        public let state: RecordingConfigurationState
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(arn: String, destinationConfiguration: DestinationConfiguration, name: String? = nil, state: RecordingConfigurationState, tags: [String: String]? = nil) {
            self.arn = arn
            self.destinationConfiguration = destinationConfiguration
            self.name = name
            self.state = state
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case destinationConfiguration = "destinationConfiguration"
            case name = "name"
            case state = "state"
            case tags = "tags"
        }
    }

    public struct RenditionConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Indicates which renditions are recorded for a stream, if renditionSelection is CUSTOM; otherwise, this field is irrelevant. The selected renditions are recorded if they are available during the stream. If a selected rendition is unavailable, the best available rendition is recorded. For details on the resolution dimensions of each rendition, see Auto-Record to Amazon S3.
        public let renditions: [RenditionConfigurationRendition]?
        /// Indicates which set of renditions are recorded for a stream. For BASIC channels, the CUSTOM value has no effect. If CUSTOM is specified, a set of renditions must be specified in the renditions field. Default: ALL.
        public let renditionSelection: RenditionConfigurationRenditionSelection?

        @inlinable
        public init(renditions: [RenditionConfigurationRendition]? = nil, renditionSelection: RenditionConfigurationRenditionSelection? = nil) {
            self.renditions = renditions
            self.renditionSelection = renditionSelection
        }

        private enum CodingKeys: String, CodingKey {
            case renditions = "renditions"
            case renditionSelection = "renditionSelection"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        /// Request references a resource which does not exist.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct S3DestinationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Location (S3 bucket name) where recorded videos will be stored.
        public let bucketName: String

        @inlinable
        public init(bucketName: String) {
            self.bucketName = bucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.bucketName, name: "bucketName", parent: name, max: 63)
            try self.validate(self.bucketName, name: "bucketName", parent: name, min: 3)
            try self.validate(self.bucketName, name: "bucketName", parent: name, pattern: "^[a-z0-9-.]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case bucketName = "bucketName"
        }
    }

    public struct ServiceQuotaExceededException: AWSErrorShape {
        /// Request would cause a service quota to be exceeded.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct Srt: AWSDecodableShape {
        /// The endpoint to be used when streaming with IVS using the SRT protocol.
        public let endpoint: String?
        /// Auto-generated passphrase to enable encryption. This field is applicable only if the end user has not enabled the insecureIngest option for the channel.
        public let passphrase: String?

        @inlinable
        public init(endpoint: String? = nil, passphrase: String? = nil) {
            self.endpoint = endpoint
            self.passphrase = passphrase
        }

        private enum CodingKeys: String, CodingKey {
            case endpoint = "endpoint"
            case passphrase = "passphrase"
        }
    }

    public struct StartViewerSessionRevocationRequest: AWSEncodableShape {
        /// The ARN of the channel associated with the viewer session to revoke.
        public let channelArn: String
        /// The ID of the viewer associated with the viewer session to revoke. Do not use this field for personally identifying, confidential, or sensitive information.
        public let viewerId: String
        /// An optional filter on which versions of the viewer session to revoke. All versions less than or equal to the specified version will be revoked. Default: 0.
        public let viewerSessionVersionsLessThanOrEqualTo: Int?

        @inlinable
        public init(channelArn: String, viewerId: String, viewerSessionVersionsLessThanOrEqualTo: Int? = nil) {
            self.channelArn = channelArn
            self.viewerId = viewerId
            self.viewerSessionVersionsLessThanOrEqualTo = viewerSessionVersionsLessThanOrEqualTo
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.validate(self.viewerId, name: "viewerId", parent: name, max: 40)
            try self.validate(self.viewerId, name: "viewerId", parent: name, min: 1)
            try self.validate(self.viewerSessionVersionsLessThanOrEqualTo, name: "viewerSessionVersionsLessThanOrEqualTo", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case viewerId = "viewerId"
            case viewerSessionVersionsLessThanOrEqualTo = "viewerSessionVersionsLessThanOrEqualTo"
        }
    }

    public struct StartViewerSessionRevocationResponse: AWSDecodableShape {
        public init() {}
    }

    public struct StopStreamRequest: AWSEncodableShape {
        /// ARN of the channel for which the stream is to be stopped.
        public let channelArn: String

        @inlinable
        public init(channelArn: String) {
            self.channelArn = channelArn
        }

        public func validate(name: String) throws {
            try self.validate(self.channelArn, name: "channelArn", parent: name, max: 128)
            try self.validate(self.channelArn, name: "channelArn", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
        }
    }

    public struct StopStreamResponse: AWSDecodableShape {
        public init() {}
    }

    public struct Stream: AWSDecodableShape {
        /// Channel ARN for the stream.
        public let channelArn: String?
        /// The stream’s health.
        public let health: StreamHealth?
        /// URL of the master playlist, required by the video player to play the HLS stream.
        public let playbackUrl: String?
        /// Time of the stream’s start. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var startTime: Date?
        /// The stream’s state. Do not rely on the OFFLINE state, as the API may not return it; instead, a "NotBroadcasting" error will indicate that the stream is not live.
        public let state: StreamState?
        /// Unique identifier for a live or previously live stream in the specified channel.
        public let streamId: String?
        /// A count of concurrent views of the stream. Typically, a new view appears in viewerCount within 15 seconds of when video playback starts and a view is removed from viewerCount within 1 minute of when video playback ends. A value of -1 indicates that the request timed out; in this case, retry.
        public let viewerCount: Int64?

        @inlinable
        public init(channelArn: String? = nil, health: StreamHealth? = nil, playbackUrl: String? = nil, startTime: Date? = nil, state: StreamState? = nil, streamId: String? = nil, viewerCount: Int64? = nil) {
            self.channelArn = channelArn
            self.health = health
            self.playbackUrl = playbackUrl
            self.startTime = startTime
            self.state = state
            self.streamId = streamId
            self.viewerCount = viewerCount
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case health = "health"
            case playbackUrl = "playbackUrl"
            case startTime = "startTime"
            case state = "state"
            case streamId = "streamId"
            case viewerCount = "viewerCount"
        }
    }

    public struct StreamEvent: AWSDecodableShape {
        /// Provides additional details about the stream event. There are several values; the long descriptions are provided in the IVS console but not delivered through the IVS API or EventBridge. Multitrack-related codes are used only for certain Session Ended events.    MultitrackInputNotAllowed — The broadcast client attempted to connect with multitrack input, but multitrack input was not enabled on the channel. Check your broadcast software settings or set MultitrackInputConfiguration.Policy to ALLOW or REQUIRE.    MultitrackInputRequired — The broadcast client attempted to connect with single-track video, but multitrack input is required on this channel. Enable multitrack video in your broadcast software or configure the channel’s MultitrackInputConfiguration.Policy to ALLOW.    InvalidGetClientConfigurationStreamKey — The broadcast client attempted to connect with an invalid, expired, or corrupt stream key.    GetClientConfigurationStreamKeyRequired — The broadcast client attempted to stream multitrack video without providing an authenticated stream key from GetClientConfiguration.    InvalidMultitrackInputTrackCount — The multitrack input stream contained an invalid number of tracks.    InvalidMultitrackInputVideoTrackMediaProperties — The multitrack input stream contained one or more tracks with an invalid codec, resolution, bitrate, or framerate.    StreamTakeoverMediaMismatch — The broadcast client attempted to take over with different media properties (e.g., codec, resolution, or video track type) from the original stream.    StreamTakeoverInvalidPriority — The broadcast client attempted a takeover with either a priority integer value equal to or lower than the original stream's value or a value outside the allowed range of 1 to 2,147,483,647.  StreamTakeoverLimitBreached — The broadcast client reached the maximum allowed takeover attempts for this stream.
        public let code: String?
        /// Time when the event occurred. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var eventTime: Date?
        /// Name that identifies the stream event within a type.
        public let name: String?
        /// Logical group for certain events.
        public let type: String?

        @inlinable
        public init(code: String? = nil, eventTime: Date? = nil, name: String? = nil, type: String? = nil) {
            self.code = code
            self.eventTime = eventTime
            self.name = name
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case code = "code"
            case eventTime = "eventTime"
            case name = "name"
            case type = "type"
        }
    }

    public struct StreamFilters: AWSEncodableShape {
        /// The stream’s health.
        public let health: StreamHealth?

        @inlinable
        public init(health: StreamHealth? = nil) {
            self.health = health
        }

        private enum CodingKeys: String, CodingKey {
            case health = "health"
        }
    }

    public struct StreamKey: AWSDecodableShape {
        /// Stream-key ARN.
        public let arn: String?
        /// Channel ARN for the stream.
        public let channelArn: String?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?
        /// Stream-key value.
        public let value: String?

        @inlinable
        public init(arn: String? = nil, channelArn: String? = nil, tags: [String: String]? = nil, value: String? = nil) {
            self.arn = arn
            self.channelArn = channelArn
            self.tags = tags
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case channelArn = "channelArn"
            case tags = "tags"
            case value = "value"
        }
    }

    public struct StreamKeySummary: AWSDecodableShape {
        /// Stream-key ARN.
        public let arn: String?
        /// Channel ARN for the stream.
        public let channelArn: String?
        /// Tags attached to the resource. Array of 1-50 maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(arn: String? = nil, channelArn: String? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.channelArn = channelArn
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case channelArn = "channelArn"
            case tags = "tags"
        }
    }

    public struct StreamSession: AWSDecodableShape {
        /// The properties of the channel at the time of going live.
        public let channel: Channel?
        /// Time when the channel went offline. This is an ISO 8601 timestamp; note that this is returned as a string. For live streams, this is NULL.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var endTime: Date?
        /// The properties of the incoming RTMP stream.  Note: ingestConfiguration is deprecated in favor of ingestConfigurations but retained to ensure backward compatibility. If multitrack is not enabled, ingestConfiguration and ingestConfigurations contain the same data, namely information about track0 (the sole track). If multitrack is enabled, ingestConfiguration contains data for only the first track (track0) and ingestConfigurations contains data for all tracks.
        public let ingestConfiguration: IngestConfiguration?
        /// The properties of the incoming RTMP stream. If multitrack is enabled, ingestConfigurations contains data for all tracks; otherwise, it contains data only for track0 (the sole track).
        public let ingestConfigurations: IngestConfigurations?
        /// The properties of recording the live stream.
        public let recordingConfiguration: RecordingConfiguration?
        /// Time when the channel went live. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var startTime: Date?
        /// Unique identifier for a live or previously live stream in the specified channel.
        public let streamId: String?
        /// List of Amazon IVS events that the stream encountered. The list is sorted by most recent events and contains up to 500 events. For Amazon IVS events, see Using Amazon EventBridge with Amazon IVS.
        public let truncatedEvents: [StreamEvent]?

        @inlinable
        public init(channel: Channel? = nil, endTime: Date? = nil, ingestConfiguration: IngestConfiguration? = nil, ingestConfigurations: IngestConfigurations? = nil, recordingConfiguration: RecordingConfiguration? = nil, startTime: Date? = nil, streamId: String? = nil, truncatedEvents: [StreamEvent]? = nil) {
            self.channel = channel
            self.endTime = endTime
            self.ingestConfiguration = ingestConfiguration
            self.ingestConfigurations = ingestConfigurations
            self.recordingConfiguration = recordingConfiguration
            self.startTime = startTime
            self.streamId = streamId
            self.truncatedEvents = truncatedEvents
        }

        private enum CodingKeys: String, CodingKey {
            case channel = "channel"
            case endTime = "endTime"
            case ingestConfiguration = "ingestConfiguration"
            case ingestConfigurations = "ingestConfigurations"
            case recordingConfiguration = "recordingConfiguration"
            case startTime = "startTime"
            case streamId = "streamId"
            case truncatedEvents = "truncatedEvents"
        }
    }

    public struct StreamSessionSummary: AWSDecodableShape {
        /// Time when the channel went offline. This is an ISO 8601 timestamp; note that this is returned as a string. For live streams, this is NULL.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var endTime: Date?
        /// If true, this stream encountered a quota breach or failure.
        public let hasErrorEvent: Bool?
        /// Time when the channel went live. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var startTime: Date?
        /// Unique identifier for a live or previously live stream in the specified channel.
        public let streamId: String?

        @inlinable
        public init(endTime: Date? = nil, hasErrorEvent: Bool? = nil, startTime: Date? = nil, streamId: String? = nil) {
            self.endTime = endTime
            self.hasErrorEvent = hasErrorEvent
            self.startTime = startTime
            self.streamId = streamId
        }

        private enum CodingKeys: String, CodingKey {
            case endTime = "endTime"
            case hasErrorEvent = "hasErrorEvent"
            case startTime = "startTime"
            case streamId = "streamId"
        }
    }

    public struct StreamSummary: AWSDecodableShape {
        /// Channel ARN for the stream.
        public let channelArn: String?
        /// The stream’s health.
        public let health: StreamHealth?
        /// Time of the stream’s start. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var startTime: Date?
        /// The stream’s state. Do not rely on the OFFLINE state, as the API may not return it; instead, a "NotBroadcasting" error will indicate that the stream is not live.
        public let state: StreamState?
        /// Unique identifier for a live or previously live stream in the specified channel.
        public let streamId: String?
        /// A count of concurrent views of the stream. Typically, a new view appears in viewerCount within 15 seconds of when video playback starts and a view is removed from viewerCount within 1 minute of when video playback ends. A value of -1 indicates that the request timed out; in this case, retry.
        public let viewerCount: Int64?

        @inlinable
        public init(channelArn: String? = nil, health: StreamHealth? = nil, startTime: Date? = nil, state: StreamState? = nil, streamId: String? = nil, viewerCount: Int64? = nil) {
            self.channelArn = channelArn
            self.health = health
            self.startTime = startTime
            self.state = state
            self.streamId = streamId
            self.viewerCount = viewerCount
        }

        private enum CodingKeys: String, CodingKey {
            case channelArn = "channelArn"
            case health = "health"
            case startTime = "startTime"
            case state = "state"
            case streamId = "streamId"
            case viewerCount = "viewerCount"
        }
    }

    public struct StreamUnavailable: AWSErrorShape {
        /// The stream is temporarily unavailable.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// ARN of the resource for which tags are to be added or updated. The ARN must be URL-encoded.
        public let resourceArn: String
        /// Array of tags to be added or updated. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 128)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:[a-z-]/[a-zA-Z0-9-]+$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ThrottlingException: AWSErrorShape {
        /// Request was denied due to request throttling.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct ThumbnailConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Thumbnail recording mode. Default: INTERVAL.
        public let recordingMode: RecordingMode?
        /// Indicates the desired resolution of recorded thumbnails. Thumbnails are recorded at the selected resolution if the corresponding rendition is available during the stream; otherwise, they are recorded at source resolution. For more information about resolution values and their corresponding height and width dimensions, see Auto-Record to Amazon S3. Default: Null (source resolution is returned).
        public let resolution: ThumbnailConfigurationResolution?
        /// Indicates the format in which thumbnails are recorded. SEQUENTIAL records all generated thumbnails in a serial manner, to the media/thumbnails directory. LATEST saves the latest thumbnail in media/latest_thumbnail/thumb.jpg and overwrites it at the interval specified by targetIntervalSeconds. You can enable both SEQUENTIAL and LATEST. Default: SEQUENTIAL.
        public let storage: [ThumbnailConfigurationStorage]?
        /// The targeted thumbnail-generation interval in seconds. This is configurable (and required) only if recordingMode is INTERVAL. Default: 60.  Important: For the BASIC channel type, or the STANDARD channel type with multitrack input, setting a value for targetIntervalSeconds does not guarantee that thumbnails are generated at the specified interval. For thumbnails to be generated at the targetIntervalSeconds interval, the IDR/Keyframe value for the input video must be less than the targetIntervalSeconds value. See  Amazon IVS Streaming Configuration for information on setting IDR/Keyframe to the recommended value in video-encoder settings.
        public let targetIntervalSeconds: Int64?

        @inlinable
        public init(recordingMode: RecordingMode? = nil, resolution: ThumbnailConfigurationResolution? = nil, storage: [ThumbnailConfigurationStorage]? = nil, targetIntervalSeconds: Int64? = nil) {
            self.recordingMode = recordingMode
            self.resolution = resolution
            self.storage = storage
            self.targetIntervalSeconds = targetIntervalSeconds
        }

        public func validate(name: String) throws {
            try self.validate(self.targetIntervalSeconds, name: "targetIntervalSeconds", parent: name, max: 60)
            try self.validate(self.targetIntervalSeconds, name: "targetIntervalSeconds", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case recordingMode = "recordingMode"
            case resolution = "resolution"
            case storage = "storage"
            case targetIntervalSeconds = "targetIntervalSeconds"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// ARN of the resource for which tags are to be removed. The ARN must be URL-encoded.
        public let resourceArn: String
        /// Array of tags to be removed. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS has no service-specific constraints beyond what is documented there.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 128)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:[a-z-]/[a-zA-Z0-9-]+$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateChannelRequest: AWSEncodableShape {
        /// ARN of the channel to be updated.
        public let arn: String
        /// Whether the channel is private (enabled for playback authorization).
        public let authorized: Bool?
        /// Indicates which content-packaging format is used (MPEG-TS or fMP4). If multitrackInputConfiguration is specified and enabled is true, then containerFormat is required and must be set to FRAGMENTED_MP4. Otherwise, containerFormat may be set to TS or FRAGMENTED_MP4. Default: TS.
        public let containerFormat: ContainerFormat?
        /// Whether the channel allows insecure RTMP and SRT ingest. Default: false.
        public let insecureIngest: Bool?
        /// Channel latency mode. Use NORMAL to broadcast and deliver live video up to Full HD. Use LOW for near-real-time interaction with viewers.
        public let latencyMode: ChannelLatencyMode?
        /// Object specifying multitrack input configuration. Default: no multitrack input configuration is specified.
        public let multitrackInputConfiguration: MultitrackInputConfiguration?
        /// Channel name.
        public let name: String?
        /// Playback-restriction-policy ARN. A valid ARN value here both specifies the ARN and enables playback restriction. If this is set to an empty string, playback restriction policy is disabled.
        public let playbackRestrictionPolicyArn: String?
        /// Optional transcode preset for the channel. This is selectable only for ADVANCED_HD and ADVANCED_SD channel types. For those channel types, the default preset is HIGHER_BANDWIDTH_DELIVERY. For other channel types (BASIC and STANDARD), preset is the empty string ("").
        public let preset: TranscodePreset?
        /// Recording-configuration ARN. A valid ARN value here both specifies the ARN and enables recording. If this is set to an empty string, recording is disabled.
        public let recordingConfigurationArn: String?
        /// Channel type, which determines the allowable resolution and bitrate. If you exceed the allowable input resolution or bitrate, the stream probably will disconnect immediately. Default: STANDARD. For details, see Channel Types.
        public let type: ChannelType?

        @inlinable
        public init(arn: String, authorized: Bool? = nil, containerFormat: ContainerFormat? = nil, insecureIngest: Bool? = nil, latencyMode: ChannelLatencyMode? = nil, multitrackInputConfiguration: MultitrackInputConfiguration? = nil, name: String? = nil, playbackRestrictionPolicyArn: String? = nil, preset: TranscodePreset? = nil, recordingConfigurationArn: String? = nil, type: ChannelType? = nil) {
            self.arn = arn
            self.authorized = authorized
            self.containerFormat = containerFormat
            self.insecureIngest = insecureIngest
            self.latencyMode = latencyMode
            self.multitrackInputConfiguration = multitrackInputConfiguration
            self.name = name
            self.playbackRestrictionPolicyArn = playbackRestrictionPolicyArn
            self.preset = preset
            self.recordingConfigurationArn = recordingConfigurationArn
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:channel/[a-zA-Z0-9-]+$")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.validate(self.playbackRestrictionPolicyArn, name: "playbackRestrictionPolicyArn", parent: name, max: 128)
            try self.validate(self.playbackRestrictionPolicyArn, name: "playbackRestrictionPolicyArn", parent: name, pattern: "^^$|^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-restriction-policy/[a-zA-Z0-9-]+$$")
            try self.validate(self.recordingConfigurationArn, name: "recordingConfigurationArn", parent: name, max: 128)
            try self.validate(self.recordingConfigurationArn, name: "recordingConfigurationArn", parent: name, pattern: "^^$|^arn:aws:ivs:[a-z0-9-]+:[0-9]+:recording-configuration/[a-zA-Z0-9-]+$$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case authorized = "authorized"
            case containerFormat = "containerFormat"
            case insecureIngest = "insecureIngest"
            case latencyMode = "latencyMode"
            case multitrackInputConfiguration = "multitrackInputConfiguration"
            case name = "name"
            case playbackRestrictionPolicyArn = "playbackRestrictionPolicyArn"
            case preset = "preset"
            case recordingConfigurationArn = "recordingConfigurationArn"
            case type = "type"
        }
    }

    public struct UpdateChannelResponse: AWSDecodableShape {
        /// Object specifying the updated channel.
        public let channel: Channel?

        @inlinable
        public init(channel: Channel? = nil) {
            self.channel = channel
        }

        private enum CodingKeys: String, CodingKey {
            case channel = "channel"
        }
    }

    public struct UpdatePlaybackRestrictionPolicyRequest: AWSEncodableShape {
        /// A list of country codes that control geoblocking restriction. Allowed values are the officially assigned ISO 3166-1 alpha-2 codes. Default: All countries (an empty array).
        public let allowedCountries: [String]?
        /// A list of origin sites that control CORS restriction. Allowed values are the same as valid values of the Origin header defined at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin. Default: All origins (an empty array).
        public let allowedOrigins: [String]?
        /// ARN of the playback-restriction-policy to be updated.
        public let arn: String
        /// Whether channel playback is constrained by origin site. Default: false.
        public let enableStrictOriginEnforcement: Bool?
        /// Playback-restriction-policy name. The value does not need to be unique.
        public let name: String?

        @inlinable
        public init(allowedCountries: [String]? = nil, allowedOrigins: [String]? = nil, arn: String, enableStrictOriginEnforcement: Bool? = nil, name: String? = nil) {
            self.allowedCountries = allowedCountries
            self.allowedOrigins = allowedOrigins
            self.arn = arn
            self.enableStrictOriginEnforcement = enableStrictOriginEnforcement
            self.name = name
        }

        public func validate(name: String) throws {
            try self.allowedCountries?.forEach {
                try validate($0, name: "allowedCountries[]", parent: name, max: 2)
                try validate($0, name: "allowedCountries[]", parent: name, min: 2)
            }
            try self.allowedOrigins?.forEach {
                try validate($0, name: "allowedOrigins[]", parent: name, max: 128)
            }
            try self.validate(self.arn, name: "arn", parent: name, max: 128)
            try self.validate(self.arn, name: "arn", parent: name, min: 1)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:aws:ivs:[a-z0-9-]+:[0-9]+:playback-restriction-policy/[a-zA-Z0-9-]+$")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case allowedCountries = "allowedCountries"
            case allowedOrigins = "allowedOrigins"
            case arn = "arn"
            case enableStrictOriginEnforcement = "enableStrictOriginEnforcement"
            case name = "name"
        }
    }

    public struct UpdatePlaybackRestrictionPolicyResponse: AWSDecodableShape {
        /// Object specifying the updated policy.
        public let playbackRestrictionPolicy: PlaybackRestrictionPolicy?

        @inlinable
        public init(playbackRestrictionPolicy: PlaybackRestrictionPolicy? = nil) {
            self.playbackRestrictionPolicy = playbackRestrictionPolicy
        }

        private enum CodingKeys: String, CodingKey {
            case playbackRestrictionPolicy = "playbackRestrictionPolicy"
        }
    }

    public struct ValidationException: AWSErrorShape {
        /// The input fails to satisfy the constraints specified by an Amazon Web Services service.
        public let exceptionMessage: String?

        @inlinable
        public init(exceptionMessage: String? = nil) {
            self.exceptionMessage = exceptionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case exceptionMessage = "exceptionMessage"
        }
    }

    public struct VideoConfiguration: AWSDecodableShape {
        /// Indicates the degree of required decoder performance for a profile. Normally this is set automatically by the encoder. For details, see the H.264 specification.
        public let avcLevel: String?
        /// Indicates to the decoder the requirements for decoding the stream. For definitions of the valid values, see the H.264 specification.
        public let avcProfile: String?
        /// Codec used for the video encoding.
        public let codec: String?
        /// Software or hardware used to encode the video.
        public let encoder: String?
        /// Indicates the degree of required decoder performance for a profile. Normally this is set automatically by the encoder. When an AVC codec is used, this field has the same value as avcLevel.
        public let level: String?
        /// Indicates to the decoder the requirements for decoding the stream. When an AVC codec is used, this field has the same value as avcProfile.
        public let profile: String?
        /// The expected ingest bitrate (bits per second). This is configured in the encoder.
        public let targetBitrate: Int64?
        /// The expected ingest framerate. This is configured in the encoder.
        public let targetFramerate: Int64?
        /// Name of the video track. If multitrack is not enabled, this is track0 (the sole track).
        public let track: String?
        /// Video-resolution height in pixels.
        public let videoHeight: Int64?
        /// Video-resolution width in pixels.
        public let videoWidth: Int64?

        @inlinable
        public init(avcLevel: String? = nil, avcProfile: String? = nil, codec: String? = nil, encoder: String? = nil, level: String? = nil, profile: String? = nil, targetBitrate: Int64? = nil, targetFramerate: Int64? = nil, track: String? = nil, videoHeight: Int64? = nil, videoWidth: Int64? = nil) {
            self.avcLevel = avcLevel
            self.avcProfile = avcProfile
            self.codec = codec
            self.encoder = encoder
            self.level = level
            self.profile = profile
            self.targetBitrate = targetBitrate
            self.targetFramerate = targetFramerate
            self.track = track
            self.videoHeight = videoHeight
            self.videoWidth = videoWidth
        }

        private enum CodingKeys: String, CodingKey {
            case avcLevel = "avcLevel"
            case avcProfile = "avcProfile"
            case codec = "codec"
            case encoder = "encoder"
            case level = "level"
            case profile = "profile"
            case targetBitrate = "targetBitrate"
            case targetFramerate = "targetFramerate"
            case track = "track"
            case videoHeight = "videoHeight"
            case videoWidth = "videoWidth"
        }
    }
}

// MARK: - Errors

/// Error enum for IVS
public struct IVSErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case channelNotBroadcasting = "ChannelNotBroadcasting"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case pendingVerification = "PendingVerification"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case streamUnavailable = "StreamUnavailable"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize IVS
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    public static var channelNotBroadcasting: Self { .init(.channelNotBroadcasting) }
    public static var conflictException: Self { .init(.conflictException) }
    public static var internalServerException: Self { .init(.internalServerException) }
    public static var pendingVerification: Self { .init(.pendingVerification) }
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    public static var streamUnavailable: Self { .init(.streamUnavailable) }
    public static var throttlingException: Self { .init(.throttlingException) }
    public static var validationException: Self { .init(.validationException) }
}

extension IVSErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "AccessDeniedException": IVS.AccessDeniedException.self,
        "ChannelNotBroadcasting": IVS.ChannelNotBroadcasting.self,
        "ConflictException": IVS.ConflictException.self,
        "InternalServerException": IVS.InternalServerException.self,
        "PendingVerification": IVS.PendingVerification.self,
        "ResourceNotFoundException": IVS.ResourceNotFoundException.self,
        "ServiceQuotaExceededException": IVS.ServiceQuotaExceededException.self,
        "StreamUnavailable": IVS.StreamUnavailable.self,
        "ThrottlingException": IVS.ThrottlingException.self,
        "ValidationException": IVS.ValidationException.self
    ]
}

extension IVSErrorType: Equatable {
    public static func == (lhs: IVSErrorType, rhs: IVSErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension IVSErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
